<?php
/**
 * Created by PhpStorm.
 * User: meng
 * Date: 2023/9/6
 * Time: 09:16
 */

namespace app\admin\service;

use lib\common\CommonService;
use lib\exception\NotFoundException;
use lib\exception\ParamsException;
use lib\utils\CacheUtils;
use model\AdminMenuModel;
use model\AdminPermissionMenuModel;

class MenuService extends CommonService
{
    private AdminMenuModel $menuModel;

    const MENU_LIST_CACHE_KEY = 'admin_menu:list';

    /**
     * @param AdminMenuModel $menuModel
     */
    public function __construct (AdminMenuModel $menuModel) {
        parent::__construct();
        $this->menuModel = $menuModel;
    }


    public function menuList ($force = false): array {
        if (!$this->enableCache || $force) {
            return $this->menuModel->order(['list_order' => 'DESC', 'id' => 'ASC'])->select()->toArray();
        } else {
            return CacheUtils::rememberForever(self::MENU_LIST_CACHE_KEY, function () {
                return $this->menuModel->order(['list_order' => 'DESC', 'id' => 'ASC'])->select()->toArray();
            });
        }
    }

    public function permissionMenuList ($permissionIds): array {
        $menus = $this->menuList();
        if (in_array(1, $permissionIds)) {
            return $menus;
        }
        // 查找权限菜单
        $menuIds = make(AdminPermissionMenuModel::class)->distinct(true)->where('permission_id', 'in', $permissionIds)->column('menu_id');
        return empty($menuIds) ? [] : array_values(array_filter($menus, function ($item) use ($menuIds) {
            return in_array($item['id'], $menuIds);
        }));
    }

    public function findMenu ($id) {
        $menu = $this->menuModel->find($id);
        if (empty($menu)) {
            throw new NotFoundException('菜单不存在');
        }
        return $menu;
    }

    public function create ($params): void {
        $this->menuModel::create($params, $this->menuModel::ALLOWED_FIELDS);
        $this->clearMenuListCache();
    }

    public function delete ($id): void {
        $menu = $this->findMenu($id);
        // 查看是否有子菜单
        $child = $this->menuModel->where('parent_id', $id)->find();
        if (!empty($child)) {
            throw new ParamsException('当前菜单下有子菜单无法删除');
        }
        $menu->delete();
        $this->clearMenuListCache();
    }

    public function update ($id, $params): void {
        $menu = $this->findMenu($id);
        $menu->allowField($this->menuModel::ALLOWED_FIELDS)->save($params);
    }

    public function clearMenuListCache (): bool {
        return CacheUtils::forget(self::MENU_LIST_CACHE_KEY);
    }
}
